﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace FezLogForSns
{
	public partial class MainForm : Form
	{
		public MainForm()
		{
			InitializeComponent();

            //設定の反映
            AppConfig conf = Program.Config;
            string[] range = Constant.Range;

            foreach (string type in range)
            {
                Control[] cText = this.Controls.Find("textColor_" + type, true);
                Control[] cEnable = this.Controls.Find("checkEnable_" + type, true);
                Control[] cBold = this.Controls.Find("checkBold_" + type, true);
                Control[] cItalic = this.Controls.Find("checkItalic_" + type, true);
                Control[] cButton = this.Controls.Find("buttonChangeColor_" + type, true);
                Control[] cLabel = this.Controls.Find("labelSample_" + type, true);

                if (cText.Length > 0)
                {
                    ((TextBox)cText[0]).Text = conf.colorCode[type];
                    ((TextBox)cText[0]).Enabled = conf.checkStatus[type];
                }

                if (cEnable.Length > 0) ((CheckBox)cEnable[0]).Checked = conf.checkStatus[type];
                if (cBold.Length > 0)
                {
                    ((CheckBox)cBold[0]).Checked = conf.checkBold[type];
                    ((CheckBox)cBold[0]).Enabled = conf.checkStatus[type];
                }
                if (cItalic.Length > 0)
                {
                    ((CheckBox)cItalic[0]).Checked = conf.checkItalic[type];
                    ((CheckBox)cItalic[0]).Enabled = conf.checkStatus[type];
                }
                if (cButton.Length > 0) ((Button)cButton[0]).Enabled = conf.checkStatus[type];
                if (cLabel.Length > 0) ((Label)cLabel[0]).Visible = conf.checkStatus[type];
            }

            textExportDirectory.Text = conf.exportDirectory;

            if (conf.convertTarget != "1")
            {
                radioFileClipBoard.Checked = true;
                textExportDirectory.Enabled = false;
                buttonExportDirectoryOpen.Enabled = false;
            }

            refreshFont();
		}

        /// <summary>
        /// サンプルラベルの色を現在のカラーコードに書き換える
        /// </summary>
        private void refreshFont()
        {
            string[] range = Constant.Range;
            string colorCode = "";
            foreach (string target in range)
            {
                Control[] label = Controls.Find("labelSample_" + target, true);
                if (label.Length == 0) continue;

                Control[] color = Controls.Find("textColor_" + target, true);
                if (color.Length != 0)
                {
                    colorCode = ((TextBox)color[0]).Text;

                    if (AppUtil.isValidColorCode(colorCode))
                    {
                        ((Label)label[0]).ForeColor = ColorTranslator.FromHtml("#" + colorCode);
                    }
                }
                
                Font oldFont = ((Label)label[0]).Font;
                bool isBold = false;
                bool isItalic = false;

                Control[] bold = Controls.Find("checkBold_" + target, true);
                if (bold.Length != 0)
                {
                    isBold = ((CheckBox)bold[0]).Checked;
                }

                Control[] italic = Controls.Find("checkItalic_" + target, true);
                if (italic.Length != 0)
                {
                    isItalic = ((CheckBox)italic[0]).Checked;
                }

                FontStyle style = FontStyle.Regular;
                if (isBold) style = style | FontStyle.Bold;
                if (isItalic) style = style | FontStyle.Italic;

                ((Label)label[0]).Font = new Font(oldFont, style);
            }
        }

        /// <summary>
        /// 変換のメイン処理
        /// </summary>
        /// <param name="files"></param>
        public void runConvert(string[] files)
        {
            AppConfig conf = Program.Config;
            LogConverter converter = new LogConverter(conf.checkStatus, conf.checkBold, conf.checkItalic, conf.colorCode);            

            // ファイル出力
            if (conf.convertTarget == "1")
            {
                string dir = conf.exportDirectory;
                // ファイルとして出力
                if (dir == "")
                {
                    dir = Program.BasePath;
                }
                else if (!Directory.Exists(dir))
                {
                    if (!Path.IsPathRooted(dir))
                    {
                        dir = Program.BasePath + "\\" + dir; 
                    }


                    if (AppUtil.showOkCancelDlg("指定されたディレクトリは存在しません。\n作成してもよろしいですか？") != DialogResult.OK)
                    {
                        return;
                    }

                    Directory.CreateDirectory(dir);

                    if (!Directory.Exists(dir))
                    {
                        AppUtil.showMsgWarning("ディレクトリの作成に失敗しました。");
                        return;
                    }
                }

                bool error = false;
                foreach (string file in files)
                {
                    try
                    {
                        using (StreamReader sr = new StreamReader(file, Encoding.GetEncoding("shift_jis")))
                        {
                            string data = sr.ReadToEnd();
                            if (!converter.run(data))
                            {
                                error = true;
                                continue;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        error = true;
                        continue;
                    }


                    try
                    {
                        string exportFile = dir + "\\" + Path.GetFileName(file) + ".txt";
                        File.WriteAllText(exportFile, converter.getResult(), Encoding.GetEncoding("shift_jis"));
                    }
                    catch (Exception)
                    {
                        error = true;
                    }

                }

                if (error)
                {
                    AppUtil.showMsgWarning("一部のファイルの変換・出力に失敗しました。");
                }
                else
                {
                    AppUtil.showMsgInfo("正常にファイルを出力しました。");
                }

                return;
            }

            // クリップボードにコピー
            if (files.Length == 1)
            {
                string file = files[0];

                try
                {
                    using (StreamReader sr = new StreamReader(file, Encoding.GetEncoding("shift_jis")))
                    {
                        string data = sr.ReadToEnd();
                        if (!converter.run(data))
                        {
                            AppUtil.showMsgWarning(converter.getError().label());
                            return;
                        }
                    }
                }
                catch (Exception)
                {
                    AppUtil.showMsgWarning("ファイルの読み込みに失敗しました。");
                    return;
                }

                // クリップボードにコピー
                Clipboard.SetText(converter.getResult());
                AppUtil.showMsgInfo("クリップボードに変換したテキストをコピーしました。");
            }
            else if (files.Length > 1)
            {
                AppUtil.showMsgWarning("クリップボードにコピーする機能は\n複数のファイル変換には対応していません。");
            }
        }

        #region イベント

        /// <summary>
        /// 参照ボタン
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonExportDirectoryOpen_Click(object sender, EventArgs e)
		{
			if (DialogResult.OK == exportFolderDlg.ShowDialog())
			{
				textExportDirectory.Text = exportFolderDlg.SelectedPath;
                Program.Config.exportDirectory = exportFolderDlg.SelectedPath;
			}
		}

        /// <summary>
        /// 出力先ディレクトリを直接書き換え
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textExportDirectory_TextChanged(object sender, EventArgs e)
        {
            Program.Config.exportDirectory = ((TextBox)sender).Text;
        }

        /// <summary>
        /// ラジオボタンの切り替え
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void radioTarget_Change(object sender, EventArgs e)
        {
            string tag = (string)((RadioButton)sender).Tag;
            Program.Config.convertTarget = tag;
            bool enable = tag == "1";
            textExportDirectory.Enabled = enable;
            buttonExportDirectoryOpen.Enabled = enable;
        }

        /// <summary>
        /// チェックボックス　有効無効の変更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkEnable_Change(object sender, EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;

            string tag = (string)cb.Tag;

            Control[] cBold = this.Controls.Find("checkBold_" + tag, true);
            Control[] cItalic = this.Controls.Find("checkItalic_" + tag, true);
            Control[] cText = this.Controls.Find("textColor_" + tag, true);
            Control[] cButton = this.Controls.Find("buttonChangeColor_" + tag, true);
            Control[] cLabel = this.Controls.Find("labelSample_" + tag, true);

            if (cBold.Length > 0) ((CheckBox)cBold[0]).Enabled = cb.Checked;
            if (cItalic.Length > 0) ((CheckBox)cItalic[0]).Enabled = cb.Checked;

            if (cText.Length > 0) ((TextBox)cText[0]).Enabled = cb.Checked;
            if (cButton.Length > 0) ((Button)cButton[0]).Enabled = cb.Checked;
            if (cLabel.Length > 0) ((Label)cLabel[0]).Visible = cb.Checked;

            Program.Config.checkStatus[tag] = cb.Checked;
        }

        /// <summary>
        /// 太字チェックボックス　ON
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkBold_Change(object sender, EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;
            string tag = (string)cb.Tag;
            Program.Config.checkBold[tag] = cb.Checked;
            refreshFont();
        }

        /// <summary>
        /// 太字チェックボックス　ON
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkItalic_Change(object sender, EventArgs e)
        {
            CheckBox cb = (CheckBox)sender;
            string tag = (string)cb.Tag;
            Program.Config.checkItalic[tag] = cb.Checked;
            refreshFont();
        }

        /// <summary>
        /// 色の変更がクリックされたイベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonChangeColor_Click(object sender, EventArgs e)
        {
            if (DialogResult.OK == colorDialog.ShowDialog())
            {
                Color selected = colorDialog.Color;
                string colorCode = "";
                colorCode += Convert.ToString(selected.R, 16).PadLeft(2, '0').ToUpper();
                colorCode += Convert.ToString(selected.G, 16).PadLeft(2, '0').ToUpper();
                colorCode += Convert.ToString(selected.B, 16).PadLeft(2, '0').ToUpper();

                if (!AppUtil.isValidColorCode(colorCode))
                {
                    return;
                }

                bool flg = AppUtil.isValidColorCode(colorCode);

                string tag = (string)((Button)sender).Tag;
                Control[] cs = this.Controls.Find("textColor_" + tag, true);

                if (cs.Length > 0)
                {
                    Program.Config.colorCode[tag] = colorCode;
                    ((TextBox)cs[0]).Text = colorCode;
                    refreshFont();
                }
            }
        }

        /// <summary>
        /// カラーテキストの入力制限
        /// 
        /// 0-9a-fA-Fまで入力可能
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textColor_Changing(object sender, TextChangingEventArgs e)
        {
            System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("[^0-9A-Fa-f]");
            if (r.Match(e.ChangedText).Success == true)
            {
                e.Cancel = true;
            }
        }

        /// <summary>
        /// カラーテキストとして正規化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textColor_Leave(object sender, EventArgs e)
        {
            ChangingTextBox box = (ChangingTextBox)sender;
            string colorCode = box.Text;

            colorCode = colorCode.PadLeft(6, '0').ToUpper();

            if (!AppUtil.isValidColorCode(colorCode))
            {
                colorCode = "000000";
            }

            box.Text = colorCode;

            string tag = (string)box.Tag;
            Program.Config.colorCode[tag] = colorCode;

            refreshFont();
        }

        /// <summary>
        /// ファイルのドロップエンター
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panelDrop_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }

        /// <summary>
        /// ファイルのドロップ処理 メイン処理がはしる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void panelDrop_DragDrop(object sender, DragEventArgs e)
        {
            TopMost = true;
            runConvert((string[])e.Data.GetData(DataFormats.FileDrop));
            TopMost = false;
        }

        /// <summary>
        /// ストリップメニュー　このソフトウェアについてをクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stripMenuAbout_Click(object sender, EventArgs e)
        {
            AppUtil.showAboutDlg();
        }

        /// <summary>
        /// ストリップメニュー　終了をクリック
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void stripMenuExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        /// <summary>
        /// アプリケーション終了前処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void formCloseingEvent(object sender, FormClosingEventArgs e)
        {
            if (AppUtil.showOkCancelDlg("アプリケーションを終了します。\nよろしいですか？") != DialogResult.OK)
            {
                e.Cancel = true;
            }
            else
            {
                Program.Config.save();
            }
        }

        #endregion    
	}
}
